﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GabageFactory.Models;
using System.IO;

namespace GabageFactory.Controllers
{
    [Authorize]
    public class StackController : BaseController
    {
        private StackReposity stackReposity;

        private StackRainfallReposity stackRainfallReposity;

        private MaterialReposity materialReposity;

        private DikeReposity dikeReposity;

        private PoolReposity poolReposity;
        
        public StackController()
        {
            stackReposity = new StackReposity();
            stackRainfallReposity = new StackRainfallReposity();
            materialReposity = new MaterialReposity();
            dikeReposity = new DikeReposity();
            poolReposity = new PoolReposity();
        }
        
        //
        // GET: /Stack/

        public ActionResult Index(string name, int? factoryId)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            int fId = factoryId.HasValue ? factoryId.Value : 0;
            ShowFactoryList(fId);
            return View(stackReposity.QueryStacks(name, fId));
        }

        //
        // GET: /Stack/Details/5

        public ActionResult Details(int id)
        {
            List<RoleEnum> roles = new List<RoleEnum> ();
            roles.Add(RoleEnum.Auditor);
            roles.Add(RoleEnum.Manager);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }
            Stack stack = stackReposity.GetStackById(id);
            return View(stack);
        }

        //
        // GET: /Stack/Create

        public ActionResult Create()
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ShowFactoryList(0);
            return View(new Stack());
        } 

        //
        // POST: /Stack/Create

        [HttpPost]
        public ActionResult Create(Stack stack, HttpPostedFileWrapper fileSummaryPic, HttpPostedFileWrapper fileFlowInPic, HttpPostedFileWrapper filePic1, HttpPostedFileWrapper filePic2, HttpPostedFileWrapper filePic3)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            try
            {
                if (fileSummaryPic != null)
                {
                    string fileName = UploadFile(fileSummaryPic);

                    stack.SummaryPic = fileName;
                }

                if (fileFlowInPic != null)
                {
                    var fileName = UploadFile(fileFlowInPic);
                    stack.FlowInPic = fileName;
                }

                if (filePic1 != null)
                {
                    var fileName = UploadFile(filePic1);
                    stack.Pic1 = fileName;
                }

                if (filePic2 != null)
                {
                    var fileName = UploadFile(filePic2);
                    stack.Pic2 = fileName;
                }

                if (filePic3 != null)
                {
                    var fileName = UploadFile(filePic3);
                    stack.Pic3 = fileName;
                }
                
                stack = stackReposity.CreateStack(stack);

                return RedirectToAction("Index");
            }
            catch
            {
                return View(stack);
            }
        }
        
        //
        // GET: /Stack/Edit/5
 
        public ActionResult Edit(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            
            Stack stack = stackReposity.GetStackById(id);
            ShowFactoryList(stack.FactoryId);
            ViewData["id"] = id;
            ViewData["SummaryPic"] = stack.SummaryPic;
            ViewData["FlowInPic"] = stack.FlowInPic;
            ViewData["Pic1"] = stack.Pic1;
            ViewData["Pic2"] = stack.Pic2;
            ViewData["Pic3"] = stack.Pic3;

            return View(stack);
        }

        //
        // POST: /Stack/Edit/5

        [HttpPost]
        public ActionResult Edit(Stack stack, HttpPostedFileWrapper fileSummaryPic, HttpPostedFileWrapper fileFlowInPic, HttpPostedFileWrapper filePic1, HttpPostedFileWrapper filePic2, HttpPostedFileWrapper filePic3)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            try
            {
                validate(stack);

                Stack oldStack = stackReposity.GetStackById(stack.Id);
                oldStack.Name = stack.Name;
                oldStack.Description = stack.Description;
                oldStack.Address = stack.Address;
                oldStack.BeginMonth = stack.BeginMonth;
                oldStack.BeginYear = stack.BeginYear;
                oldStack.FactoryId = stack.FactoryId;
                oldStack.GeoPosition = stack.GeoPosition;
                oldStack.LifeTime = stack.LifeTime;


                if (fileSummaryPic != null)
                {
                    string fileName = UploadFile(fileSummaryPic);

                    oldStack.SummaryPic = fileName;
                }

                if (fileFlowInPic != null)
                {
                    var fileName = UploadFile(fileFlowInPic);
                    oldStack.FlowInPic = fileName;
                }

                if (filePic1 != null)
                {
                    var fileName = UploadFile(filePic1);
                    oldStack.Pic1 = fileName;
                }

                if (filePic2 != null)
                {
                    var fileName = UploadFile(filePic2);
                    oldStack.Pic2 = fileName;
                }

                if (filePic3 != null)
                {
                    var fileName = UploadFile(filePic3);
                    oldStack.Pic3 = fileName;
                }

                stackReposity.EditStack(oldStack);
                return RedirectToAction("Index");
            }
            catch
            {
                ShowFactoryList(stack.FactoryId);
                ViewData["id"] = stack.Id;
                ViewData["SummaryPic"] = stack.SummaryPic;
                ViewData["FlowInPic"] = stack.FlowInPic;
                ViewData["Pic1"] = stack.Pic1;
                ViewData["Pic2"] = stack.Pic2;
                ViewData["Pic3"] = stack.Pic3;
                return View();
            }
        }

        //
        // GET: /Stack/Delete/5
 
        public ActionResult Delete(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            Stack stack = stackReposity.GetStackById(id);
            ViewData["Name"] = stack.Name;

            ViewData["Success"] = true;
            stackReposity.DeleteStack(stack);
            return View();
        }

        //
        // GET: /Stack/Weather/5

        public ActionResult Weather(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ViewData["success"] = false;
            IEnumerable<Stack_Rainfall_Evaporation_Base_info> rainfalls = stackRainfallReposity.ListRainfalls(id);
            Stack_Rainfall_Evaporation_Base_info[] rainfallArray = rainfalls.ToArray();
            Weather weather = new Weather();
            for (int i = 0; i < 12; i++)
            {
                if (i < rainfallArray.Length)
                {
                    weather.Months[i] = rainfallArray[i];
                }
                else
                {
                    Stack_Rainfall_Evaporation_Base_info rainfall = new Stack_Rainfall_Evaporation_Base_info();
                    rainfall.stack_id = id;
                    rainfall.month_no = i + 1;
                    weather.Months[i] = rainfall;
                }
            }
            ViewData["id"] = id;

            return View(weather);
        }

        //
        // POST: /Stack/Weather/5

        [HttpPost]
        public ActionResult Weather(FormCollection collection)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ViewData["success"] = false;
            Weather weather = new Weather();
            try
            {
                for (int i = 0; i < weather.Months.Length; i++)
                {
                    string stackIdKey = string.Format("Months[{0}].stack_id", i);
                    string monthNoKey = string.Format("Months[{0}].month_no", i);
                    string monthMaxKey = string.Format("Months[{0}].rainfall_max", i);
                    string monthMinKey = string.Format("Months[{0}].rainfall_min", i);
                    string monthAvgKey = string.Format("Months[{0}].ranfall_avg", i);
                    string monthEvaMaxKey = string.Format("Months[{0}].evaporation_max", i);
                    string monthEvaMinKey = string.Format("Months[{0}].evaporation_min", i);
                    string monthEvaAvgKey = string.Format("Months[{0}].evaporation_avg", i);
                    string monthPanMaxKey = string.Format("Months[{0}].pan_evaporation_max", i);
                    string monthPanMinKey = string.Format("Months[{0}].pan_evaporation_min", i);
                    string monthPanAvgKey = string.Format("Months[{0}].pan_evaporation_avg", i);
                    Stack_Rainfall_Evaporation_Base_info rainfall = new Stack_Rainfall_Evaporation_Base_info();
                    rainfall.stack_id = parseInt(collection.Get(stackIdKey));
                    rainfall.month_no = parseInt(collection.Get(monthNoKey));
                    rainfall.rainfall_max = parseFloat(collection.Get(monthMaxKey));
                    rainfall.rainfall_min = parseFloat(collection.Get(monthMinKey));
                    rainfall.ranfall_avg = parseFloat(collection.Get(monthAvgKey));
                    rainfall.evaporation_max = parseFloat(collection.Get(monthEvaMaxKey));
                    rainfall.evaporation_min = parseFloat(collection.Get(monthEvaMinKey));
                    rainfall.evaporation_avg = parseFloat(collection.Get(monthEvaAvgKey));
                    rainfall.pan_evaporation_avg = parseFloat(collection.Get(monthPanAvgKey));
                    rainfall.pan_evaporation_max = parseFloat(collection.Get(monthPanMaxKey));
                    rainfall.pan_evaporation_min = parseFloat(collection.Get(monthPanMinKey));
                    weather.Months[i] = rainfall;
                    ViewData["id"] = rainfall.stack_id;
                }
                
                // TODO: Add delete logic here
                for (int i = 0; i < weather.Months.Length; i++ )
                {
                    
                    
                    Stack_Rainfall_Evaporation_Base_info rainfall = weather.Months[i];

                    Stack_Rainfall_Evaporation_Base_info oldRainfall = stackRainfallReposity.GetRainfallByStackIdAndMonthNo(rainfall.stack_id, rainfall.month_no);

                    if (oldRainfall == null)
                    {
                        stackRainfallReposity.CreateRainfall(rainfall);
                    }
                    else
                    {
                        oldRainfall.evaporation_avg = rainfall.evaporation_avg;
                        oldRainfall.evaporation_max = rainfall.evaporation_max;
                        oldRainfall.evaporation_min = rainfall.evaporation_min;
                        oldRainfall.pan_evaporation_avg = rainfall.pan_evaporation_avg;
                        oldRainfall.pan_evaporation_max = rainfall.pan_evaporation_max;
                        oldRainfall.pan_evaporation_min = rainfall.pan_evaporation_min;
                        oldRainfall.ranfall_avg = rainfall.ranfall_avg;
                        oldRainfall.rainfall_max = rainfall.rainfall_max;
                        oldRainfall.rainfall_min = rainfall.rainfall_min;

                        stackRainfallReposity.EditRainfall(oldRainfall);
                    }
                }
                ViewData["success"] = true;

                return View(weather);
            }
            catch
            {
                return View(weather);
            }
        }

        //
        // GET: /Stack/Material/5

        public ActionResult Material(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }

            ViewData["id"] = id;
            ViewData["success"] = false;
            Phosphogypsum_Property materail = materialReposity.GetMaterialById(id);
            if (materail == null)
            {
                materail = new Phosphogypsum_Property();
                materail.stack_id = id;

            }

            return View(materail);
        }

        //
        // POST: /Stack/Weather/5

        [HttpPost]
        public ActionResult Material(Phosphogypsum_Property material)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            
            try
            {
                ViewData["success"] = false;
                ViewData["id"] = material.stack_id;
                Phosphogypsum_Property oldMaterial = materialReposity.GetMaterialById(material.stack_id);
                if (oldMaterial == null)
                {
                    materialReposity.CreateMaterial(material);
                }
                else
                {
                    oldMaterial.material_property_A = material.material_property_A;
                    oldMaterial.material_property_B = material.material_property_B;
                    oldMaterial.material_property_C = material.material_property_C;
                    oldMaterial.material_property_ca = material.material_property_ca;
                    oldMaterial.material_property_cc = material.material_property_cc;
                    oldMaterial.material_property_e0 = material.material_property_e0;
                    oldMaterial.material_property_n = material.material_property_n;
                    oldMaterial.material_property_p0 = material.material_property_p0;
                    oldMaterial.material_property_t0 = material.material_property_t0;

                    materialReposity.EditMaterial(oldMaterial);
                }

                ViewData["success"] = true;
                return View(material);
            }
            catch
            {
                return View(material);
            }
        }

        //
        // GET: /Stack/Stack/5
        public ActionResult Stack(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ViewData["id"] = id;
            ViewData["success"] = false;

            Seperator_Dike_Base_Info dike = dikeReposity.GetSeperatorDikeById(id);
            if (dike == null)
            {
                dike = new Seperator_Dike_Base_Info() ;
                dike.stack_id = id;
            }
            ViewData["dike"] = dike;

            Stack_Base_Info stackBaseInfo = dikeReposity.GetStackBaseInfoById(id);
            if (stackBaseInfo == null)
            {
                stackBaseInfo = new Stack_Base_Info();
                stackBaseInfo.stack_id = id;
            }
            ViewData["stackBaseInfo"] = stackBaseInfo;

            Stack_Base_Layer_Info[] stackBaseLayerInfos = new Stack_Base_Layer_Info[1];
            stackBaseLayerInfos[0] = new Stack_Base_Layer_Info();
            IEnumerable<Stack_Base_Layer_Info> layers = dikeReposity.ListStackBaseLayerInfos(id);
            if (layers != null && layers.Count() > 0)
            {
                stackBaseLayerInfos = layers.ToArray();
            }
            ViewData["stackBaseLayerInfos"] = stackBaseLayerInfos;
            ViewData["aboveEls"] = dikeReposity.ListStackElAreaBaseInfos(id, 0);
            ViewData["bottomEls1"] = dikeReposity.ListStackElAreaBaseInfos(id, 1);
            ViewData["bottomEls2"] = dikeReposity.ListStackElAreaBaseInfos(id, 2);

            return View();
        }


        //
        // POST: /Stack/Stack/5
        [HttpPost]
        public ActionResult Stack(FormCollection collection)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }

            int id = parseInt(collection.Get("id"));
            if (id <= 0)
            {
                throw new Exception();
            }
            ViewData["id"] = id;
            Seperator_Dike_Base_Info dike = new Seperator_Dike_Base_Info();
            dike.stack_id = id;
            dike.seperator_dike_1_tilt_rate = parseFloat(collection.Get("seperator_dike_1_tilt_rate"));
            dike.seperator_dike_2_tile_rate = parseFloat(collection.Get("seperator_dike_2_tile_rate"));
            dike.seperator_dike_base_El = parseFloat(collection.Get("seperator_dike_base_El"));
            dike.seperator_dike_top_El = parseFloat(collection.Get("seperator_dike_top_El"));
            dike.seperator_dike_no = 1;
            

            Seperator_Dike_Base_Info oldDike = dikeReposity.GetSeperatorDikeById(id);
            if (oldDike == null)
            {
                dikeReposity.CreateSeperatorDike(dike);
            }
            else
            {
                oldDike.seperator_dike_1_tilt_rate = dike.seperator_dike_1_tilt_rate;
                oldDike.seperator_dike_2_tile_rate = dike.seperator_dike_2_tile_rate;
                oldDike.seperator_dike_base_El = dike.seperator_dike_base_El;
                oldDike.seperator_dike_top_El = dike.seperator_dike_top_El;
                dikeReposity.EditDike(oldDike);
            }
            ViewData["dike"] = dike;

            int totalLayerNumber = parseInt(collection.Get("totalLayerNum"));
            Stack_Base_Info stackBaseInfo = new Stack_Base_Info();
            stackBaseInfo.stack_id = id;
            stackBaseInfo.initial_dike_tilt_rate = parseFloat(collection.Get("initial_dike_tilt_rate"));
            stackBaseInfo.stack_base_contour = parseFloat(collection.Get("stack_base_contour"));
            stackBaseInfo.stack_base_x = parseFloat(collection.Get("stack_base_x"));
            stackBaseInfo.first_layer_tilt_rate = parseFloat(collection.Get("first_layer_tilt_rate"));
            stackBaseInfo.first_layer_ditch_width = parseFloat(collection.Get("first_layer_ditch_width"));
            stackBaseInfo.first_layer_ditch_El = parseFloat(collection.Get("first_layer_ditch_El"));
            stackBaseInfo.total_layer_number = totalLayerNumber;
            stackBaseInfo.seperator_dike_no = 1;

            Stack_Base_Info oldStackBaseInfo = dikeReposity.GetStackBaseInfoById(id);
            if (oldStackBaseInfo != null)
            {
                dikeReposity.DeleteStackBaseInfo(oldStackBaseInfo);
            }
            dikeReposity.CreateStackBaseInfo(stackBaseInfo);
            ViewData["stackBaseInfo"] = stackBaseInfo;

            dikeReposity.DeleteStackBaseLayerInfos(id);
            List<Stack_Base_Layer_Info> stackBaseLayerInfos = new List<Stack_Base_Layer_Info>();
            for (int i = 2; i <= totalLayerNumber; i++)
            {
                Stack_Base_Layer_Info layer = new Stack_Base_Layer_Info();
                layer.layer_tilt_rate = parseFloat(collection.Get("layer_tilt_rate" + i));
                layer.layer_dike_width = parseFloat(collection.Get("layer_dike_width" + i));
                layer.layer_dike_El = parseFloat(collection.Get("layer_dike_El" + i));
                layer.layer_ditch_width = parseFloat(collection.Get("layer_ditch_width" + i));
                layer.layer_ditch_tilt_rate = parseFloat(collection.Get("layer_ditch_tilt_rate" + i));
                layer.layer_ditch_depth = parseFloat(collection.Get("layer_ditch_depth" + i));
                layer.stack_id = id;
                layer.layer_number = i;
                stackBaseLayerInfos.Add(layer);
                dikeReposity.CreateStackBaseLayerInfo(layer);
            }

            ViewData["stackBaseLayerInfos"] = stackBaseLayerInfos.ToArray();

            dikeReposity.DeleteStackElAreaBaseInfos(id);
            string aboveEls = collection.Get("aboveEls");
            storeElSlopes(aboveEls, id, 0);
            string bottomEls1 = collection.Get("bottomEls1");
            storeEls(bottomEls1, id, 1);
            string bottomEls2 = collection.Get("bottomEls2");
            storeEls(bottomEls2, id, 2);

            ViewData["aboveEls"] = dikeReposity.ListStackElAreaBaseInfos(id, 0);
            ViewData["bottomEls1"] = dikeReposity.ListStackElAreaBaseInfos(id, 1);
            ViewData["bottomEls2"] = dikeReposity.ListStackElAreaBaseInfos(id, 2);
            ViewData["success"] = true;

            return View();
        }

        //
        // GET: /Stack/Settle/5
        public ActionResult Settle(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ViewData["id"] = id;
            ViewData["success"] = false;

            string equation = "";
            IEnumerable<InitStack_FittingEquation> equations = stackReposity.ListEquations(id);
            if (equations != null && equations.Count() > 0)
            {
                foreach(InitStack_FittingEquation e in equations)
                {
                    equation = equation + e.start_level + "-" + e.end_level + ":" + e.Coefficient_A0 + "," + e.Coefficient_A1 + "," + e.Coefficient_A2 + "," + e.Coefficient_A3 + "," + e.Coefficient_A4 + "," + e.Coefficient_A5 + "\n";
                }
            }
            ViewData["equation"] = equation;

            return View();
        }


        //
        // POST: /Stack/Settle/5
        [HttpPost]
        public ActionResult Settle(FormCollection collection)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }

            int id = parseInt(collection.Get("id"));
            if (id <= 0)
            {
                throw new Exception();
            }
            ViewData["id"] = id;

            string equationStr = collection.Get("equation");
            stackReposity.DeleteEquations(id);
            storeEquations(equationStr, id);

            string equation = "";
            IEnumerable<InitStack_FittingEquation> equations = stackReposity.ListEquations(id);
            if (equations != null && equations.Count() > 0)
            {
                foreach (InitStack_FittingEquation e in equations)
                {
                    equation = equation + e.start_level + "-" + e.end_level + ":" + e.Coefficient_A0 + "," + e.Coefficient_A1 + "," + e.Coefficient_A2 + "," + e.Coefficient_A3 + "," + e.Coefficient_A4 + "," + e.Coefficient_A5 + "\n";
                }
            }
            ViewData["equation"] = equation;
            
            ViewData["success"] = true;

            return View();
        }

        //
        // GET: /Stack/Pool/5
        public ActionResult Pool(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ViewData["id"] = id;
            ViewData["success"] = false;

            IEnumerable<Return_Water_Pond_Base_Info> pools = poolReposity.ListPools(id);
            Return_Water_Pond_Base_Info[] poolArray = new Return_Water_Pond_Base_Info[1];
            Return_Water_Pond_Base_Info pool = new Return_Water_Pond_Base_Info();
            pool.stack_id = id;
            pool.pond_no = 1;
            poolArray[0] = pool;
            if (pools != null && pools.Count() > 0)
            {
                poolArray = pools.ToArray();
            }
            ViewData["pools"] = poolArray;

            string[] poolElArray = new string[poolArray.Length];
            for (int i = 0; i < poolArray.Length; i++ )
            {
                Return_Water_Pond_Base_Info pooltmp = poolArray[i];
                IEnumerable < Return_Water_Pond_El_Area_Base_Info > poolEls = poolReposity.GetPoolEls(pooltmp.stack_id, pooltmp.pond_no);
                string ElStr = "";
                if (poolEls != null && poolEls.Count() > 0)
                {
                    foreach(Return_Water_Pond_El_Area_Base_Info poolEl in poolEls)
                    {
                        ElStr = ElStr + poolEl.El + "-" + poolEl.Area + "\n";
                    }
                }

                poolElArray[i] = ElStr;
            }
            ViewData["poolElArray"] = poolElArray;

            IEnumerable<Runoff_Interception_Ditch_Base_Info> ditches = poolReposity.ListDitches(id);
            Runoff_Interception_Ditch_Base_Info[] ditchArray = new Runoff_Interception_Ditch_Base_Info[1];
            Runoff_Interception_Ditch_Base_Info ditch = new Runoff_Interception_Ditch_Base_Info();
            ditch.stack_id = id;
            ditch.ditch_no = 1;
            ditchArray[0] = ditch;
            if (ditches != null && ditches.Count() > 0)
            {
                ditchArray = ditches.ToArray();
            }
            ViewData["ditches"] = ditchArray;

            Stack stack = stackReposity.GetStackById(id);
            ViewData["poolDesignPic"] = stack.PoolDesignPic;
            ViewData["ditchDesignPic"] = stack.DitchDesignPic;

            return View();
        }

        //
        // POST: /Stack/Pool/5
        [HttpPost]
        public ActionResult Pool(FormCollection collection, HttpPostedFileWrapper poolDesignPic, HttpPostedFileWrapper ditchDesignPic)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }

            int id = parseInt(collection.Get("id"));
            if (id <= 0)
            {
                throw new Exception();
            }
            ViewData["id"] = id;

            Stack stack = stackReposity.GetStackById(id);
            

            if (poolDesignPic != null)
            {
                string fileName = UploadFile(poolDesignPic);

                if (stack != null)
                {
                    stack.PoolDesignPic = fileName;
                }
            }

            if (ditchDesignPic != null)
            {
                var fileName = UploadFile(ditchDesignPic);

                if (stack != null)
                {
                    stack.DitchDesignPic = fileName;
                }
            }

            if (stack != null && (poolDesignPic != null || ditchDesignPic != null))
            {
                stackReposity.EditStack(stack);
            }

            int totalPoolNumber = parseInt(collection.Get("totalPoolNum"));
            poolReposity.DeletePools(id);
            poolReposity.DeletePoolEls(id);
            List<Return_Water_Pond_Base_Info> pools = new List<Return_Water_Pond_Base_Info>();
            for (int i = 1; i <= totalPoolNumber; i++)
            {
                Return_Water_Pond_Base_Info pool = new Return_Water_Pond_Base_Info();
                pool.base_El = parseFloat(collection.Get("base_El" + i));
                pool.base_area = parseFloat(collection.Get("base_area" + i));
                pool.top_EL = parseFloat(collection.Get("top_EL" + i));
                pool.top_area = parseFloat(collection.Get("top_area" + i));
                pool.middle_avg_water_area = parseFloat(collection.Get("middle_avg_water_area" + i));
                pool.avg_slope_HDPE_area = parseFloat(collection.Get("avg_slope_HDPE_area" + i));
                pool.Min_Depth = parseFloat(collection.Get("Min_Depth" + i));
                pool.Avg_Depth = parseFloat(collection.Get("Avg_Depth" + i));
                pool.Avg_Depth_max = parseFloat(collection.Get("Avg_Depth_max" + i));
                pool.stack_id = id;
                pool.pond_no = i;
                pools.Add(pool);
                poolReposity.CreatePool(pool);

                string El_areas = collection.Get("El_areas" + i);
                storePoolEls(El_areas, id, i);
            }
            Return_Water_Pond_Base_Info[] poolArray = pools.ToArray();
            ViewData["pools"] = poolArray;

            
            string[] poolElArray = new string[poolArray.Length];
            for (int i = 0; i < poolArray.Length; i++)
            {
                Return_Water_Pond_Base_Info pooltmp = poolArray[i];
                IEnumerable<Return_Water_Pond_El_Area_Base_Info> poolEls = poolReposity.GetPoolEls(pooltmp.stack_id, pooltmp.pond_no);
                string ElStr = "";
                if (poolEls != null && poolEls.Count() > 0)
                {
                    foreach (Return_Water_Pond_El_Area_Base_Info poolEl in poolEls)
                    {
                        ElStr = ElStr + poolEl.El + "-" + poolEl.Area + "\n";
                    }
                }

                poolElArray[i] = ElStr;
            }
            ViewData["poolElArray"] = poolElArray;

            int totalDitchNumber = parseInt(collection.Get("totalDitchNum"));

            poolReposity.DeleteDitches(id);
            List<Runoff_Interception_Ditch_Base_Info> ditches = new List<Runoff_Interception_Ditch_Base_Info>();
            for (int i = 1; i <= totalDitchNumber; i++)
            {
                Runoff_Interception_Ditch_Base_Info ditch = new Runoff_Interception_Ditch_Base_Info();
                ditch.El = parseFloat(collection.Get("ditch_El" + i));
                ditch.Area = parseFloat(collection.Get("ditch_Area" + i));
                ditch.length = parseFloat(collection.Get("ditch_length" + i));
                ditch.position = parseInt(collection.Get("ditch_position" + i));
                ditch.unused = parseInt(collection.Get("ditch_unused" + i));
                ditch.stack_id = id;
                ditch.ditch_no = i;
                ditches.Add(ditch);
                poolReposity.CreateDitch(ditch);
            }

            ViewData["ditches"] = ditches.ToArray();
            ViewData["success"] = true;

            ViewData["poolDesignPic"] = stack.PoolDesignPic;
            ViewData["ditchDesignPic"] = stack.DitchDesignPic;

            return View();
        }


        //
        // GET: /Stack/Pool/5
        public ActionResult Piezometer(int id, bool success = false)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ViewData["id"] = id;
            ViewData["success"] = success;

            PiezometerReposity piezometerReposity = new PiezometerReposity();
            IEnumerable<Piezometer_well_base_info> wells = piezometerReposity.ListWell(id);
            Piezometer_well_base_info[] wellArray = new Piezometer_well_base_info[1];
            Piezometer_well_base_info well = new Piezometer_well_base_info();
            well.Stack_id = id;
            well.piezometer_well_id = 1;
            wellArray[0] = well;
            if (wells != null && wells.Count() > 0)
            {
                wellArray = wells.ToArray();
            }
            ViewData["wells"] = wellArray;

            IEnumerable<Piezometer_base_info> equaps = piezometerReposity.ListEquaps(id);
            Piezometer_base_info[] topEquaps = equaps.Where(item => item.piezometer_id == 1).OrderBy(item => item.piezometer_hole_id).ToArray();
            Piezometer_base_info[] bottomEquaps = equaps.Where(item => item.piezometer_id == 2).OrderBy(item => item.piezometer_hole_id).ToArray();
            Piezometer_base_info[] topEquapArray = new Piezometer_base_info[1];
            Piezometer_base_info[] bottomEquapArray = new Piezometer_base_info[1];
            Piezometer_base_info equap = new Piezometer_base_info();
            equap.Stack_id = id;
            equap.piezometer_id = 1;
            topEquapArray[0] = equap;
            bottomEquapArray[0] = equap;
            if (topEquaps != null && topEquaps.Count() > 0)
            {
                topEquapArray = topEquaps.ToArray();
            }
            if (bottomEquaps != null && bottomEquaps.Count() > 0)
            {
                bottomEquapArray = bottomEquaps.ToArray();
            }
            ViewData["topEquaps"] = topEquapArray;
            ViewData["bottomEquaps"] = bottomEquapArray;

            Stack stack = stackReposity.GetStackById(id);
            ViewData["piezometerWellPic"] = stack.PiezometerWellPic;
            ViewData["piezometerEquapPic"] = stack.PiezometerEquapPic;

            return View();
        }

        //
        // POST: /Stack/Pool/5
        [HttpPost]
        public ActionResult Piezometer(FormCollection collection, HttpPostedFileWrapper piezometerWellPic, HttpPostedFileWrapper piezometerEquapPic)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }

            int id = parseInt(collection.Get("id"));
            if (id <= 0)
            {
                throw new Exception();
            }
            ViewData["id"] = id;

            Stack stack = stackReposity.GetStackById(id);


            if (piezometerWellPic != null)
            {
                string fileName = UploadFile(piezometerWellPic);

                if (stack != null)
                {
                    stack.PiezometerWellPic = fileName;
                }
            }

            if (piezometerEquapPic != null)
            {
                var fileName = UploadFile(piezometerEquapPic);

                if (stack != null)
                {
                    stack.PiezometerEquapPic = fileName;
                }
            }

            if (stack != null && (piezometerWellPic != null || piezometerEquapPic != null))
            {
                stackReposity.EditStack(stack);
            }
            PiezometerReposity piezometerReposity = new PiezometerReposity();
            int totalWellNumber = parseInt(collection.Get("totalWellNum"));
            piezometerReposity.DeleteWells(id);
            for (int i = 1; i <= totalWellNumber; i++)
            {
                Piezometer_well_base_info well = new Piezometer_well_base_info();
                well.Well_bottom_El = parseFloat(collection.Get("Well_bottom_El" + i));
                well.well_top_El = parseFloat(collection.Get("well_top_El" + i));
                well.Stack_id = id;
                well.piezometer_well_id = i;
                piezometerReposity.CreatePiezometerWell(well);
            }

            int totalEquapNumber = parseInt(collection.Get("totalEquapNum"));
            piezometerReposity.DeleteEquaps(id);
            for (int i = 1; i <= totalEquapNumber; i++)
            {
                for (int j = 1; j <= 2; j++)
                {
                    Piezometer_base_info equap = new Piezometer_base_info();
                    equap.Initial_Modulus = parseFloat(collection.Get("Initial_Modulus_" + j + "_" + i));
                    equap.Initial_temperature = parseFloat(collection.Get("Initial_temperature_" + j + "_" + i));
                    equap.Installation_depth = parseFloat(collection.Get("Installation_depth_" + j + "_" + i));
                    equap.Modulus_coefficient = parseFloat(collection.Get("Modulus_coefficient_" + j + "_" + i));
                    equap.piezometer_bottom_El = parseFloat(collection.Get("piezometer_bottom_El_" + j + "_" + i));
                    equap.piezometer_id = j;
                    equap.piezometer_name = collection.Get("piezometer_name_" + j + "_" + i);
                    equap.Temperature_coefficient = parseFloat(collection.Get("Temperature_coefficient_" + j + "_" + i));
                    equap.Stack_id = id;
                    equap.piezometer_hole_id = i;
                    piezometerReposity.CreatePiezometerEquap(equap);
                }
            }

            return RedirectToAction("Piezometer", new {id=id, success=true});
        }


        //
        // GET: /Stack/Pool/5
        public ActionResult Drain(int id, bool success = false)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }
            ViewData["id"] = id;
            ViewData["success"] = success;

            DrainOutletReposity drainOutletReposity = new DrainOutletReposity();
            IEnumerable<Drain_system_basic_info> drains = drainOutletReposity.ListDrains(id);
            Dictionary<Drain_system_basic_info, List<Drain_system_outlet_info>> drainOutlets = new Dictionary<Drain_system_basic_info, List<Drain_system_outlet_info>>();
            foreach (Drain_system_basic_info drain in drains)
            {
                IEnumerable<Drain_system_outlet_info> outlets = drainOutletReposity.ListDrainOutlets(drain.Stack_id, drain.El);
                List<Drain_system_outlet_info> outletList = new List<Drain_system_outlet_info>();
                foreach(Drain_system_outlet_info outlet in outlets)
                {
                    outletList.Add(outlet);
                }
                drainOutlets.Add(drain, outletList);
            }

            ViewData["drainOutlets"] = drainOutlets;

            return View();
        }

        //
        // POST: /Stack/Pool/5
        [HttpPost]
        public ActionResult Drain(FormCollection collection)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }

            int id = parseInt(collection.Get("id"));
            if (id <= 0)
            {
                throw new Exception();
            }
            ViewData["id"] = id;

            DrainOutletReposity drainOutletReposity = new DrainOutletReposity();
            int drainNum = parseInt(collection.Get("drainNum"));
            HttpFileCollectionBase files =  HttpContext.Request.Files;
            
            for (int i = 1; i <= drainNum; i++)
            {
                Drain_system_basic_info drain = new Drain_system_basic_info();
                string picName = "Pic_filepath_" + i;
                HttpPostedFileBase file = files.Get(picName);
                string fileName = null;
                if (file != null && !string.IsNullOrEmpty(file.FileName))
                {
                    fileName = UploadFile(file);
                }
                float El = parseFloat(collection.Get("El" + i));
                drain.El = El;
                drain.Stack_id = id;
                int outletNum = parseInt(collection.Get("outletNum_" + i));
                Drain_system_basic_info oldDrain = drainOutletReposity.GetDrain(id, El);
                if (!string.IsNullOrEmpty(fileName))
                {
                    drain.Pic_filepath = fileName;
                }
                else if (oldDrain != null && !string.IsNullOrEmpty(oldDrain.Pic_filepath))
                {
                    drain.Pic_filepath = oldDrain.Pic_filepath;
                }
                drainOutletReposity.DeleteDrain(id, El);
                drainOutletReposity.CreateDrain(drain);
                for (int j = 1; j <= outletNum; j++)
                {
                    string Drain_outlet_group_no = collection.Get("Drain_outlet_group_no_" + i + "_"+ j);
                    string Drain_outlet_section_no = collection.Get("Drain_outlet_section_no_" + i + "_" + j);
                    int Is_sole_outlet = parseInt(collection.Get("Is_sole_outlet_" + i + "_" + j));
                    int Is_seepage_outlet = parseInt(collection.Get("Is_seepage_outlet_" + i + "_" + j));
                    int Is_open_for_input = parseInt(collection.Get("Is_open_for_input_" + i + "_" + j));
                    int Is_In_Normal_Use = parseInt(collection.Get("Is_In_Normal_Use_" + i + "_" + j));
                    Drain_system_outlet_info outlet = new Drain_system_outlet_info();
                    outlet.Stack_id = id;
                    outlet.El = El;
                    outlet.Drain_outlet_no = j;
                    outlet.Drain_outlet_group_no = Drain_outlet_group_no;
                    outlet.Drain_outlet_section_no = Drain_outlet_section_no;
                    outlet.Is_sole_outlet = Is_sole_outlet;
                    outlet.Is_seepage_outlet = Is_seepage_outlet;
                    outlet.Is_open_for_input = Is_open_for_input;
                    outlet.Is_In_Normal_Use = Is_In_Normal_Use;
                    drainOutletReposity.CreateDrainOutlet(outlet);
                }
            }

            return RedirectToAction("Drain", new { id = id, success = true });
        }

        //
        // GET: /Stack/Monitor/5

        public ActionResult Monitor(int id)
        {
            ActionResult result = AllowForRole(RoleEnum.Administrator);
            if (result != null)
            {
                return result;
            }

            ViewData["id"] = id;
            ViewData["success"] = false;
            
            return View();
        }

        private void validate(Stack stack)
        {
            if (stack.FactoryId <= 0)
            {
                ModelState.AddModelError("Name", "所属公司不能为空");
            }
            
            if (string.IsNullOrEmpty(stack.Name))
            {
                ModelState.AddModelError("Name", "堆场名称不能为空");
            }
            else if (stack.Name.Length > 128)
            {
                ModelState.AddModelError("Name", "堆场名称不能超过128个字符");
            }

            if (string.IsNullOrEmpty(stack.Description))
            {
                ModelState.AddModelError("Description", "堆场描述不能为空");
            }
            else if (stack.Description.Length > 2000)
            {
                ModelState.AddModelError("Description", "堆场名称不能超过2000个字符");
            }

            if (!ModelState.IsValid)
            {
                throw new Exception("Input form is invalid!");
            }
        }

        private string[] strSplit(string value, string separator)
        {
            string[] result = null;
            string[] separators = {separator};
            if(!string.IsNullOrEmpty(value))
            {
                try
                {
                    result = value.Split(separators, StringSplitOptions.RemoveEmptyEntries);
                }
                catch
                {
                    //empty
                }
            }

            return result;
        }

        private void storeEls(string inputs, int stackId, int partitionNo)
        {
            string[] els = strSplit(inputs, "\n");
            if (els != null && els.Length > 0)
            {
                foreach (string elStr in els)
                {
                    string[] elProperties = strSplit(elStr, "-");
                    if (elProperties != null && elProperties.Length == 2)
                    {
                        Stack_El_Area_Base_Info el = new Stack_El_Area_Base_Info();
                        el.stack_id = stackId;
                        el.partition_no = partitionNo;
                        el.El = parseInt(elProperties[0]);
                        el.area = parseFloat(elProperties[1]);
                        dikeReposity.CreateStackElAreaBaseInfo(el);
                    }
                }
            }
        }

        private void storeElSlopes(string inputs, int stackId, int partitionNo)
        {
            string[] els = strSplit(inputs, "\n");
            if (els != null && els.Length > 0)
            {
                foreach (string elStr in els)
                {
                    string[] elProperties = strSplit(elStr, "-");
                    if (elProperties != null && elProperties.Length == 3)
                    {
                        Stack_El_Area_Base_Info el = new Stack_El_Area_Base_Info();
                        el.stack_id = stackId;
                        el.partition_no = partitionNo;
                        el.El = parseInt(elProperties[0]);
                        el.area = parseFloat(elProperties[1]);
                        el.slope_area = parseFloat(elProperties[2]);
                        dikeReposity.CreateStackElAreaBaseInfo(el);
                    }
                }
            }
        }

        private void storePoolEls(string inputs, int stackId, int pondNo)
        {
            string[] els = strSplit(inputs, "\n");
            if (els != null && els.Length > 0)
            {
                foreach (string elStr in els)
                {
                    string[] elProperties = strSplit(elStr, "-");
                    if (elProperties != null && elProperties.Length == 2)
                    {
                        Return_Water_Pond_El_Area_Base_Info el = new Return_Water_Pond_El_Area_Base_Info();
                        el.stack_id = stackId;
                        el.pond_no = pondNo;
                        el.El = parseFloat(elProperties[0]);
                        el.Area = parseFloat(elProperties[1]);
                        poolReposity.CreatePoolEl(el);
                    }
                }
            }
        }

        private void storeEquations(string equationStr, int stackId)
        {
            string[] equations = strSplit(equationStr, "\n");
            if (equations != null && equations.Length > 0)
            {
                int i = 1;
                foreach (string equation in equations)
                {
                    string[] equationProperties = strSplit(equation, ":");
                    if (equationProperties != null && equationProperties.Length == 2)
                    {
                        InitStack_FittingEquation e = new InitStack_FittingEquation();
                        e.stack_id = stackId;
                        string[]els = strSplit(equationProperties[0], "-");
                        if (els != null && els.Length == 2)
                        {
                            e.start_level = parseFloat(els[0]);
                            e.end_level = parseFloat(els[1]);
                        }
                        else
                        {
                            continue;
                        }
                        string[] settles = strSplit(equationProperties[1], ",");
                        if (settles != null && settles.Length == 6)
                        {
                            e.Coefficient_A0 = parseFloat(settles[0]);
                            e.Coefficient_A1 = parseFloat(settles[1]);
                            e.Coefficient_A2 = parseFloat(settles[2]);
                            e.Coefficient_A3 = parseFloat(settles[3]);
                            e.Coefficient_A4 = parseFloat(settles[4]);
                            e.Coefficient_A5 = parseFloat(settles[5]);
                            e.sequence = i;
                        }
                        else
                        {
                            continue;
                        }

                        stackReposity.CreateEquation(e);
                        i++;
                    }
                }
            }
        }
    }
}
